home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Sapphire Collection / Software Vault (Sapphire Collection) (Digital Impact).ISO / cdr47 / ibrary30.zip / IBRARY.DOC < prev    next >
Text File  |  1994-11-05  |  52KB  |  1,282 lines

  1.  
  2.  
  3.  
  4.                III   BBBB    RRRR     AAA    RRRR    Y   Y
  5.                 I    B   B   R   R   A   A   R   R   Y   Y
  6.                 I    B   B   R   R   A   A   R   R    Y Y
  7.                 I    BBBB    RRRR    AAAAA   RRRR      Y
  8.                 I    B   B   R R     A   A   R R       Y
  9.                 I    B   B   R  R    A   A   R  R      Y
  10.                III   BBBB    R   R   A   A   R   R     Y
  11.  
  12.                ===========================================
  13.  
  14.                          A library for ASIC 4.0
  15.  
  16.         IBRARY 3.0  Copyright (c) 1993-1994  Thomas G. Hanlin III
  17.  
  18.                 "Bringing you fine shareware since 1985"
  19.  
  20.  
  21.  
  22.     This is IBRARY, a library of over 200 routines written in assembly
  23.     language for use with 80/20 Software's ASIC compiler. You will
  24.     need ASIC 4.00 or later and a linker to use IBRARY. An assembler
  25.     is not necessary. The IBRARY collection is copyrighted and may be
  26.     distributed only under the following conditions:
  27.  
  28.        All IBRARY files must be distributed together as a unit.
  29.        No files may be altered, added, or deleted from this unit.
  30.        The assembly language sources must NOT be distributed.
  31.  
  32.     YOU USE THIS LIBRARY AT YOUR OWN RISK. I have tested it on my own
  33.     computer, but I will not assume any responsibility for any
  34.     problems which IBRARY may cause you.
  35.  
  36.     It is expected that if you find IBRARY useful, you will register
  37.     your copy. You may not use IBRARY routines in programs intended
  38.     for sale unless you have registered. See the ORDER.FRM file for
  39.     more information.
  40.  
  41.                            Table of Contents                 page 2
  42.  
  43.  
  44.  
  45.      Synopsis and Legal Info .................................... 1
  46.  
  47.      Table of Contents .......................................... 2
  48.  
  49.      Overview ................................................... 3
  50.  
  51.      Directory Services ......................................... 4
  52.  
  53.      Equipment Info ............................................. 6
  54.  
  55.      Extended Math ............................................. 10
  56.  
  57.      Files ..................................................... 11
  58.  
  59.      Graphics .................................................. 15
  60.  
  61.      Interrupts ................................................ 18
  62.  
  63.      Joystick .................................................. 19
  64.  
  65.      Keyboard .................................................. 20
  66.  
  67.      Memory PEEK/POKE........................................... 21
  68.  
  69.      Mouse ..................................................... 22
  70.  
  71.      Miscellaneous ............................................. 25
  72.  
  73.                                Overview                      page 3
  74.  
  75.  
  76.  
  77.     As of version 4.0, ASIC became a much more powerful language,
  78.     with the introduction of library support. A library is very like
  79.     an extension to a compiler. It provides capabilities which are
  80.     perhaps insufficiently general-purpose to add into the language
  81.     itself, but which may nonetheless be of use to many people.
  82.     Libraries let you customize a language to suit your particular
  83.     needs.
  84.  
  85.     The routines in IBRARY are contained in a library file, which is
  86.     denoted by the extension .LIB. So, the IBRARY library is named
  87.     IBRARY.LIB. How you access this library depends on which version
  88.     of the compiler you use: ASIC.EXE or ASICC.EXE.
  89.  
  90.     In the case of ASICC.EXE, the command to compile a program which
  91.     uses IBRARY looks something like this:
  92.  
  93.        ASICC progname B/OBJ LIB=IBRARY LNK=C:\DOS
  94.  
  95.     Here, "progname" is the name of the program to compile. When you
  96.     use a library, compilation turns into a multi-part process. ASIC
  97.     first turns your .ASI code into an .OBJ file. It then calls your
  98.     LINK.EXE program to combine the .OBJ file with the routines you
  99.     need from IBRARY.LIB, turning the result into an .EXE program.
  100.     In the above command line, the LNK=C:\DOS part tells ASIC that
  101.     it can find LINK.EXE in a directory called C:\DOS. You will need
  102.     to use the appropriate directory for your computer. Note that
  103.     LINK.EXE does not come with ASIC. It is provided with Microsoft
  104.     languages and many DOS versions, though. Borland also has a
  105.     linker, called TLINK.EXE.
  106.  
  107.     IBRARY includes a batch file, ASICMAKE.BAT, to make all this
  108.     easier. You will need to modify it to have the appropriate LNK=
  109.     setting, but once that's done, you can simply type:
  110.  
  111.        ASICMAKE progname
  112.  
  113.     ...in order to compile and link your program.
  114.  
  115.     In the case of the editor/environment, the initial setup is a
  116.     bit different. From the Compiler menu, pick Advanced Options.
  117.     From the Advanced Options menu, do the following:
  118.  
  119.        choose .OBJ output file generation
  120.        set library name to IBRARY
  121.        set link path to wherever your LINK.EXE is (e.g., C:\DOS)
  122.  
  123.     It's as easy as that! You are now set up to use libraries. A
  124.     good first test would be to compile the IBRARY quick demo,
  125.     cleverly entitled DEMO.ASI. Give it a try!
  126.  
  127.                           Directory Services                 page 4
  128.  
  129.  
  130.  
  131.     The directory service routines allow you to duplicate the basic
  132.     functionality of the DOS command, DIR. You can search for files
  133.     with wildcard filespecs and file attributes. For matching files,
  134.     you can get the filename, attributes, size, time, and date. The
  135.     two basic routines are FindFirstF, which is used to set the
  136.     search specifications and search for the first matching file,
  137.     and FindNextF, which is used to search for additional matches:
  138.  
  139.        CALL SUB "FindFirstF" FileSpec$ Attr ErrCode
  140.        CALL SUB "FindNextF" ErrCode
  141.  
  142.     The FileSpec$ may include a full path, with drive, subdirectory,
  143.     and filename with "*" and/or "?" wildcards. The attribute tells
  144.     what kinds of files you want to search for, and may be any of
  145.     the following, used individually or added together:
  146.  
  147.        0    normal files
  148.        2    hidden files
  149.        4    system files
  150.        8    volume labels
  151.       16    subdirectories
  152.  
  153.     Since normal files have an attribute of 0, they are always
  154.     included in the search. So, searching for an attribute of 6, for
  155.     example, would result in finding normal, hidden, and system
  156.     files (4 + 2 + 0 = 6). Labels are a bit different-- they are
  157.     only present in the root directory, so your search spec should
  158.     be "\*.*" (maybe with a drive spec) to search for a volume
  159.     label. When you search for a label, you "should" get only a
  160.     label in return, but some versions of DOS are buggy and return
  161.     normal files as well-- so you should check the attribute, just
  162.     as you would in any other kind of file search.
  163.  
  164.     The ErrCode returned will be 0 until you run out of matches or
  165.     there is an error. An error code of 18 means you've run out of
  166.     matches, but (for most practical purposes) you can treat any
  167.     non-zero error code as meaning "no more matching files".
  168.  
  169.     When ErrCode returns zero, you know you have a valid match. You
  170.     can get additional information about the resulting match, so:
  171.  
  172.        CALL SUB "GetAttrF" FileAttr
  173.        CALL SUB "GetNameF" FileName$
  174.        CALL SUB "GetSizeF" FileSize&
  175.        CALL SUB "GetTimeF" Hour Minute Second
  176.        CALL SUB "GetDateF" Month Day Year
  177.  
  178.     Remember that you need to set a compiler switch to use long
  179.     integers in ASIC-- see your ASIC docs for details. Note that the
  180.     filename will not contain a drive or path specification. Hours
  181.     are returned in 24-hour format (0-23, or midnight-11pm). Seconds
  182.     are rounded down to even numbers, due to the DOS storage format.
  183.  
  184.                           Directory Services                 page 5
  185.  
  186.  
  187.  
  188.     File attributes may be any or all of the following, added
  189.     together (the ZBIT function, provided by ASIC, will be useful in
  190.     decoding this info):
  191.  
  192.        0    normal files
  193.        1    read-only files                bit 0
  194.        2    hidden files                   bit 1
  195.        4    system files                   bit 2
  196.        8    volume labels                  bit 3
  197.       16    subdirectories                 bit 4
  198.       32    archive files (back-up bit)    bit 5
  199.  
  200.     Putting all this together, a simple program to display all of
  201.     the filenames in the current directory might look like this:
  202.  
  203.        PRINT "Files in this directory:"
  204.        CALL SUB "FindFirstF" FileSpec$ Attr ErrCode
  205.        WHILE ErrCode = 0
  206.           CALL SUB "GetNameF" FileName$
  207.           PRINT FileName$
  208.           CALL SUB "FindNextF" ErrCode
  209.        WEND
  210.        PRINT "End of list"
  211.  
  212.                             Equipment Info                   page 6
  213.  
  214.  
  215.  
  216.     The equipment routines give you information about the computing
  217.     environment. This includes both installed software and hardware.
  218.  
  219.     The first function allows you to determine if an "enhanced"
  220.     keyboard (101-key) is installed. It may not be able to figure
  221.     out what the keyboard is on some older not-quite-clone PCs, in
  222.     which case it will take the safe way out and report that there
  223.     is no enhanced keyboard. This routine returns -1 if there is an
  224.     enhanced keyboard present, 0 if not.
  225.  
  226.        CALL SUB "KbdType" Enhanced
  227.  
  228.     Want to know the type of processor (CPU) being used? Can do!
  229.  
  230.        CALL SUB "Processor" CPUType
  231.  
  232.     The results will be returned as a number which can be decoded as
  233.     follows:
  234.  
  235.        0    NEC V20
  236.        1    8088 or 8086
  237.        2    80186
  238.        3    80286
  239.        4    80386
  240.        5    80486
  241.  
  242.     The processor speed can also be determined, although the results
  243.     may not be exact, especially if multitasking is going on. Note
  244.     that it may take up to several seconds to determine the speed on
  245.     8088-class processors.
  246.  
  247.        CALL SUB "ProcSpeed" MHz
  248.  
  249.     You can also see whether a numeric coprocessor is installed, and
  250.     what kind it is. This is done by checking for the coprocessor
  251.     directly, rather than examining the BIOS setting or switches,
  252.     and is quite reliable.
  253.  
  254.        CALL SUB "NumProc" NumProcType
  255.  
  256.     The results will be returned as a number which can be decoded as
  257.     follows:
  258.  
  259.        0    no coprocessor installed
  260.        1    8087
  261.        2    80287
  262.        3    80387
  263.  
  264.     I expect that a 486DX chip will appear to have an 80387
  265.     coprocessor, so you should be able to tell the difference
  266.     between a 486SX and a 486DX by checking for a math chip. I
  267.     haven't been able to verify this, though-- let me know if you
  268.     can tell me for sure!
  269.  
  270.                             Equipment Info                   page 7
  271.  
  272.  
  273.  
  274.     The number of floppy drives installed is retrieved like this:
  275.  
  276.        CALL SUB "Floppies" Drives
  277.  
  278.     There may be up to four floppy drives in a system; however, the
  279.     AT CMOS data area only directly supports two. This makes it easy
  280.     to find out what kind of drives the first two are, but not the
  281.     second two. Oh well, guess we'll have to settle for what we can
  282.     get, right?
  283.  
  284.        CALL SUB "FloppyType" Drive1 Drive2
  285.  
  286.     The results from FloppyType are returned as follows:
  287.  
  288.        0    no drive
  289.        1    5 1/4"    360K
  290.        2    5 1/4"    1.2M
  291.        3    3 1/2"    720K
  292.        4    3 1/2"    1.44M
  293.  
  294.     Result codes of 5-7 are available, but not yet defined. One
  295.     might guess that the 2.88M drive supported by DOS 5.0 will be
  296.     drive type 5. Has anybody seen one of those puppies yet?
  297.  
  298.     Maybe you'd like to check for a CD-ROM drive:
  299.  
  300.        CALL SUB "CDROM" Drives
  301.  
  302.     This tells you how many logical drives exist, if there is a
  303.     CD-ROM available. If not, it will return 0. Note that the CD-ROM
  304.     installation check conflicts with the GRAPHICS.COM installation
  305.     check for DOS 4.0, due to some screw-up at IBM or Microsoft.
  306.  
  307.     You can get the letter of the current default drive, or set the
  308.     current default drive, with the following routines:
  309.  
  310.        CALL SUB "GetDrive" Drive$
  311.        CALL SUB "SetDrive" Drive$
  312.  
  313.     New memory types sure have burgeoned over the years... expanded,
  314.     extended, and now XMS. There are routines to check all of these:
  315.  
  316.        REM get total extended memory installed
  317.        CALL SUB "AllExtMem" AllExt&
  318.  
  319.        REM get BIOS extended memory installed
  320.        CALL SUB "GetExtM" BiosExt&
  321.  
  322.        REM get expanded (EMS) memory installed
  323.        CALL SUB "GetEMSm" TotalPages FreePages
  324.  
  325.        REM get XMS memory installed
  326.        CALL SUB "GetXMSm" BigFree& TotalFree&
  327.  
  328.                             Equipment Info                   page 8
  329.  
  330.  
  331.  
  332.     When you're dealing with extended memory, whether it be
  333.     BIOS-type or using the XMS standard, the results are returned in
  334.     kilobytes. Multiply 'em by 1024 to convert to bytes. When you're
  335.     dealing with expanded memory (EMS), the results are in pages of
  336.     16,384 bytes.
  337.  
  338.     I might note, by the way, that Microsoft seems to have
  339.     intentionally crippled the XMS standard. It can only support a
  340.     maximum of 64 megabytes. This may seem like a lot now, but it'll
  341.     seem cramped soon enough. I remember when 640k seemed like an
  342.     empty football stadium, best used to make a 360k RAMdisk!
  343.  
  344.     A few more routines to get the versions of EMS and XMS, if any:
  345.  
  346.        CALL SUB "GetEMSv" MajorV MinorV
  347.        CALL SUB "GetXMSv" MajorV MinorV
  348.  
  349.     These return the major and minor version numbers as two separate
  350.     integers. For example, EMS 4.0 would return major version 4,
  351.     minor version 0.
  352.  
  353.     It's nice to know a little about the operating environment. With
  354.     the below routines, you can find out what the DOS version is;
  355.     what version of 4DOS, if any, is in use; and whether Microsoft
  356.     Windows is running.
  357.  
  358.        CALL SUB "GetDOSv" MajorV MinorV
  359.        CALL SUB "Get4DOSv" MajorV MinorV
  360.        CALL SUB "WinCheck" MajorV MinorV
  361.  
  362.     These return results as major and minor version numbers, as
  363.     discussed on the previous page. The Get4DOSv and WinCheck
  364.     routines return zeroes if 4DOS and Windows, respectively, are
  365.     not available.
  366.  
  367.     There are a couple of curious features of GetDOSv to keep in
  368.     mind. If the version is 10 or higher, you're running in OS/2
  369.     compatibility mode. DOS version 10 is actually OS/2 1.0, version
  370.     20 is OS/2 2.0, and so on. Secondly, if you're using DOS 5.0,
  371.     the version reported may not be 5.0-- DOS 5.0 can be told to
  372.     reply with a lower version number to allow some older software
  373.     (which checks for a specific DOS version) to run properly.
  374.  
  375.     Another routine that may be of some value is the one that allows
  376.     you to find out what kind of display is available. It tells you
  377.     the specific adapter and whether the display is monochrome or
  378.     color. There are two cases in which it can be confused, however.
  379.     If the adapter is CGA, the display is assumed to be color, since
  380.     there is no way for the computer to know any differently. Also,
  381.     some laptops lie about their mono VGA displays, and claim that
  382.     they're color. So, although this routine provides a good idea of
  383.     what is available, it would be a good idea to provide an option
  384.     to tell the program that a monochrome display is attached.
  385.     Microsoft normally uses "/B" for this purpose, so that might be
  386.     a good standard to stick with.
  387.  
  388.                             Equipment Info                   page 9
  389.  
  390.  
  391.  
  392.        CALL SUB "GetDisplay" Adapter Mono
  393.  
  394.     This returns Mono = -1 for a monochrome display, or Mono = 0 for
  395.     a color display. The Adapter may be any of the following:
  396.  
  397.        1    MDA
  398.        2    Hercules
  399.        3    CGA
  400.        4    EGA
  401.        5    MCGA
  402.        6    VGA
  403.  
  404.     Aside from some of the oldest semi-clones, it's possible to find
  405.     out what sort of machine you're using by looking at a specific
  406.     data byte. You can access this as follows:
  407.  
  408.        CALL SUB "PCType" PcType
  409.  
  410.     The result will need decoding. Here are some known values:
  411.  
  412.        255   PC or XT          250   PS/2 Model 30
  413.        254   XT                249   PC Convertible
  414.        253   PCjr              248   PS/2 Model 70 or 80
  415.        252   PC AT             154   Compaq Portable
  416.        251   XT                 45   Compaq Portable
  417.  
  418.     Likewise, all but some of the oldest semi-clones maintain a BIOS
  419.     date value which tells you how old the BIOS ROM is. This can be
  420.     retrieved with the following routine:
  421.  
  422.        CALL SUB "PCDate" PCDate$
  423.  
  424.     If your program is running on one of the rare old machines which
  425.     don't maintain a valid BIOS date, this routine will return "No
  426.     Date " instead of an actual date.
  427.  
  428.     As far as a program is concerned, DR DOS is essentially the same
  429.     as MS-DOS. Still, it's always nice to know what sort of
  430.     operating environment you have. You can find out whether your
  431.     program is running under DR DOS with the following function:
  432.  
  433.        CALL SUB "DrDos" DrDos
  434.        IF DRDOS = 0 THEN
  435.           PRINT "MS-DOS"
  436.        ELSE
  437.           PRINT "DR DOS"
  438.        ENDIF
  439.  
  440.     The number of serial and parallel ports available can be readily
  441.     obtained:
  442.  
  443.        CALL SUB "CommPorts" CommPorts
  444.  
  445.        CALL SUB "PrtPorts" PrtPorts
  446.  
  447.                              Extended Math                  page 10
  448.  
  449.  
  450.  
  451.     The extended math routines provide a number of simple binary
  452.     functions which operate on an integer as a stream of bits. You
  453.     may shift or rotate the bits in an integer by an arbitrary
  454.     amount in either direction.
  455.  
  456.     Note that the normal ASIC integer has a length of 16 bits.
  457.  
  458.        CALL SUB "LShift" Number ShiftCount
  459.  
  460.        CALL SUB "RShift" Number ShiftCount
  461.  
  462.        CALL SUB "LRotate" Number ShiftCount
  463.  
  464.        CALL SUB "RRotate" Number ShiftCount
  465.  
  466.     An identical set of routines is provided for long integers,
  467.     which have a length of 32 bits. You need to specify a compiler
  468.     option to use long integers, as explained in the ASIC manual.
  469.  
  470.        CALL SUB "LShiftL" Number& ShiftCount
  471.  
  472.        CALL SUB "RShiftL" Number& ShiftCount
  473.  
  474.        CALL SUB "LRotateL" Number& ShiftCount
  475.  
  476.        CALL SUB "RRotateL" Number& ShiftCount
  477.  
  478.     For picking out specific bits, check out ASIC's extension to the
  479.     BASIC function set, ZBIT.
  480.  
  481.                                  Files                      page 11
  482.  
  483.  
  484.  
  485.     For sheer flexibility, it's hard to beat DOS file handling. It's
  486.     not always as convenient as BASIC file handling, but it offers
  487.     many compensating advantages. It allows up to 15 files to be
  488.     open at a time (or more, under some circumstances), instead of
  489.     ASIC's paltry 3. It provides binary access, allows you to read
  490.     large chunks of data at a time (even entire arrays!), and offers
  491.     both sequential and random-access techniques at once. IBRARY has
  492.     built-in critical error handling, so you can treat all errors
  493.     the same way (no fear of "R>etry, A>bort, I>gnore, F>ail?").
  494.  
  495.     The IBRARY file routines are designed for binary files. You can
  496.     read text files too, of course-- all files are the same to DOS--
  497.     but there is no provision for stopping at a carriage return (or
  498.     control-Z, if you're dealing with CP/M-format text files). You
  499.     can interpret such yourself, if you wish. Additional routines
  500.     will be added to the next revision of IBRARY, of course.
  501.  
  502.     When opening a file with IBRARY, you do not give it a file
  503.     number. Instead, IBRARY passes you back a file handle, if the
  504.     file was opened successfully. This file handle serves the same
  505.     purpose as a file number and is used to identify the file any
  506.     time you want to access it. It has an advantage over ASIC file
  507.     numbers in that you don't have to worry about whether you've
  508.     used a number before-- IBRARY will always give you a unique
  509.     handle for a successful open.
  510.  
  511.     Files may be opened in either of two ways. FOpen opens an
  512.     existing file, and may include an open mode (read, write, or
  513.     read/write) and sharing mode (allowing network support). FCreate
  514.     creates a new file, or wipes out and recreates an existing file,
  515.     with a specified file attribute. Generally, you will want to
  516.     take one of two approaches:
  517.  
  518.       1) If the file is expected to exist, try FOpen to open it. If
  519.       there is an error opening the file, you must decide whether to
  520.       abort the operation and tell the user "file not found" or to
  521.       create a new file with FCreate.
  522.  
  523.       2) If you are creating a new file, you may wish to try FOpen
  524.       to see if the file exists. If FOpen succeeds, you should close
  525.       the file and prompt the user "File exists: overwrite? abort?"
  526.       and act accordingly. Also, although FCreate will create a
  527.       file, it does so in a mode which is not network-friendly.
  528.       Unless you are sure your program will never run on a network
  529.       or in a multitasking situation, you should immediately close a
  530.       file created by FCreate, and use FOpen to reopen it with the
  531.       appropriate sharing mode.
  532.  
  533.     The FOpen and FCreate calls look like so:
  534.  
  535.        CALL SUB "FOpen" FileName$ OpenMode Sharing Handle ErrCode
  536.        CALL SUB "FCreate" FileName$ Attribute Handle ErrCode
  537.  
  538.                                  Files                      page 12
  539.  
  540.  
  541.  
  542.     If the file is opened or created successfully, the ErrCode will
  543.     be zero, and a valid handle will be returned. You *MUST* close
  544.     such files with FClose when you are done with them, or they will
  545.     not be updated properly on disk, and your program will lose
  546.     access to the handle involved. Do not use FClose on a file if
  547.     the FOpen or FCreate call returned a non-zero ErrCode.
  548.  
  549.     Note that there are five system handles which are provided to
  550.     every program. You can use these without having to open (or
  551.     close) them:
  552.  
  553.        0   CON   stdin    standard input, normally the keyboard
  554.        1   CON   stdout   standard output, normally the display
  555.        2   CON   stderr   standard error, almost always display
  556.        3   AUX   stdaux   auxiliary device, generally COM1
  557.        4   PRN   stdprn   standard printer, generally LPT1
  558.  
  559.     In fact, if you need more than the usual 15 handles available,
  560.     you can gain a few handles by closing these system handles. Do
  561.     not do this if your program relies on the device in question!
  562.     You can safely close AUX, though, since IBRARY uses the BIOS to
  563.     provide comm support, rather than DOS. You can probably also
  564.     close PRN without any problem (certainly if you don't use the
  565.     printer in your program). The CON handles should generally be
  566.     left alone, unless you're very sure of what you're doing.
  567.  
  568.     For FOpen, the OpenMode may be one of the following, depending
  569.     on what you intend to do with the file:
  570.  
  571.        0   Read
  572.        1   Write
  573.        2   Read and Write
  574.  
  575.     Also for FOpen, you must choose an appropriate Sharing mode. You
  576.     should normally try to use a network mode, so your program will
  577.     work well on networks and under multitasking situations. IBRARY
  578.     is smart enough to ignore the network mode if your program is
  579.     run on a DOS version below 3.0, which doesn't support network
  580.     modes. A good general guideline is to use "deny write" (or
  581.     "exclusive" if you want to be really secure) on files you expect
  582.     to write to, and "deny none" on files you expect only to read.
  583.     The Sharing mode may be one of the following:
  584.  
  585.        0   Normal       compatibility mode: no file sharing
  586.        1   Exclusive    no one else may access the file
  587.        2   Deny Write   no one else may write to the file
  588.        3   Deny Read    no one else may read from the file
  589.        4   Deny None    anyone else may read from or write to file
  590.  
  591.                                  Files                      page 13
  592.  
  593.  
  594.  
  595.     For FCreate, you may select a file attribute to apply to the
  596.     created file. This may be one or more of the following, added
  597.     together:
  598.  
  599.        Normal          0      (nothing special)
  600.        Read Only       1      file can be read, but not written to
  601.        Hidden          2      file is "invisible"
  602.        System          4      special DOS system file
  603.  
  604.     Don't use the System attribute unless you know what you're
  605.     doing. It is not appropriate for ordinary files. Files created
  606.     by FCreate are opened in Read and Write mode, with Normal
  607.     sharing. For best compatibility, you should close the file and
  608.     re-open it with FOpen, using an appropriate Sharing mode.
  609.  
  610.     The FClose routine has been mentioned several times, because
  611.     it's important. If a file was opened successfully with FOpen or
  612.     FCreate, you *MUST* close it (when you're done with it) with
  613.     FClose, or the file may be left in an indeterminate state.
  614.  
  615.        CALL SUB "FClose" Handle
  616.  
  617.     If you are writing particularly important data, you may want to
  618.     make sure its information is committed to disk at periodic
  619.     intervals. Otherwise, a system crash or power failure could
  620.     cause loss of data due to DOS disk buffering. The FFlush routine
  621.     will make sure the current data is sent to disk. Note that
  622.     FFlush works with DOS alone. If an external disk cache is in
  623.     use, it may delay the disk update beyond DOS' control.
  624.  
  625.        CALL SUB "FFlush" Handle ErrCode
  626.  
  627.     If you are dealing with files that require heavy access by many
  628.     network nodes, the file-based locking supported by FOpen is
  629.     likely to be too crude. You can lock and unlock independent
  630.     areas of a file too-- but be careful. You must unlock all locks
  631.     in the reverse order you apply them, and using the exact same
  632.     parameters (like a stack: the last lock applied must be the
  633.     first lock to be removed). All locks *MUST* be removed before
  634.     you close a file, or the file is left in an indeterminate state
  635.     and may not be recoverable. Microsoft is vague in its warnings,
  636.     but it sounds like a good place to be careful...
  637.  
  638.        CALL SUB "FLock" Handle Posn& Bytes& ErrCode
  639.        CALL SUB "FUnlock" Handle Posn& Bytes& ErrCode
  640.  
  641.     Positions start at 1, the first byte. Remember that you need to
  642.     use a special switch to get ASIC to handle long integers-- see
  643.     the ASIC manual for details.
  644.  
  645.                                  Files                      page 14
  646.  
  647.  
  648.  
  649.     You may read a byte, integer, long, or string from a file.
  650.     Better yet, you may read an array of bytes, array of integers,
  651.     or array of longs from a file-- not arrays of strings, though,
  652.     due to the different format involved. In the case of single
  653.     values, pass the variable to the call. In the case of arrays,
  654.     pass the first element of the array to the call. Note that an
  655.     integer takes up two bytes, and a long integer takes up four.
  656.  
  657.        CALL SUB "FReadB" Handle Value Bytes ErrCode
  658.        CALL SUB "FReadI" Handle Value Integers ErrCode
  659.        CALL SUB "FReadL" Handle Value& Longs ErrCode
  660.        CALL SUB "FReadS" Handle Value$ Bytes ErrCode
  661.  
  662.     Of course, you can also write values, in much the same fashion:
  663.  
  664.        CALL SUB "FWriteB" Handle Value Bytes ErrCode
  665.        CALL SUB "FWriteI" Handle Value Integers ErrCode
  666.        CALL SUB "FWriteL" Handle Value& Longs ErrCode
  667.        CALL SUB "FWriteS" Handle Value$ Bytes ErrCode
  668.  
  669.     NOTE NOTE NOTE!!! The count variable (Bytes, Integers, or Longs,
  670.     depending on the routine) is RETURNED as well as being passed to
  671.     the routine-- it tells you how many bytes were actually written
  672.     or read, in case your entire request couldn't be processed.
  673.     Don't use constants for these values, since ASIC treats
  674.     constants somewhat like variables-- the constant would be
  675.     altered throughout your program!
  676.  
  677.     Normally, when you read or write a value, the file pointer will
  678.     be updated to the next position, so you will read or write the
  679.     next area on subsequent calls. You can find out where the file
  680.     pointer is, so:
  681.  
  682.        CALL SUB "FWhere" Handle Posn&
  683.  
  684.     The file pointer can also be set to the start of the file, end
  685.     of the file, or a specified point in the file, so:
  686.  
  687.        CALL SUB "FSetStart" Handle
  688.        CALL SUB "FSetEnd" Handle
  689.        CALL SUB "FLocate" Handle Posn&
  690.  
  691.     And, finally, you can get the size of the file, or set the size
  692.     of the file:
  693.  
  694.        CALL SUB "FSize" Handle Bytes&
  695.        CALL SUB "FSetSize" Handle Bytes& ErrCode
  696.  
  697.     Being able to set the size of the file lets you trim off
  698.     unwanted material from the end of a file, or to expand a file in
  699.     advance of needing space (in order to improve the odds of
  700.     allocating contiguous disk space, for best speed).
  701.  
  702.                                Graphics                     page 15
  703.  
  704.  
  705.  
  706.     Much of the design of ASIC appears to be oriented on the notion
  707.     of creating the smallest possible programs. In that respect, it
  708.     is perhaps not surprising that ASIC doesn't include strong
  709.     graphics support. IBRARY provides support for EGA and VGA modes
  710.     which ASIC doesn't.
  711.  
  712.       Mode   Description
  713.       ====   ================================================
  714.         8    640x200,  16 colors, 80x25 text, EGA or better
  715.        11    640x480,   2 colors, 80x25 text, VGA or better
  716.        12    640x480,  16 colors, 80x25 text, VGA or better
  717.        13    320x200, 256 colors, 40x25 text, VGA or better
  718.        N0    360x480, 256 colors, 45x60 text, VGA or better
  719.        N1    320x400, 256 colors, 40x25 text, VGA or better
  720.  
  721.     The graphics routines all use the same nomenclature: a G,
  722.     followed by a mode number, followed by the specific name. This
  723.     generic naming convention is used so that this chapter can refer
  724.     to all available modes. For example, if I say "G#Color" and
  725.     you're using mode 12, you'd actually use "G12Color" in your
  726.     program. Ok?
  727.  
  728.     You just use G#Mode with a non-zero value to enter graphics
  729.     mode, or zero to restore text mode. The text mode is assumed to
  730.     be the normal 80x25 color mode. If you'd prefer to reset to
  731.     another mode, you can safely use the ASIC SCREEN statement to
  732.     pick setting that's more to your liking.
  733.  
  734.     Typical handling of one of the non-SVGA modes (in this case,
  735.     mode 12) would go something like this:
  736.  
  737.        CALL SUB "G12Mode" 1
  738.        REM *** your main program goes here ***
  739.        CALL SUB "G12Mode" 0
  740.  
  741.                                Graphics                     page 16
  742.  
  743.  
  744.  
  745.     One difference between ASIC and IBRARY is that, instead of each
  746.     "draw" command requiring a color parameter as in ASIC, IBRARY
  747.     provides a separate color command:
  748.  
  749.        CALL SUB "G#Color" Foreground Background
  750.  
  751.     The foreground color is used by all graphics routines. The
  752.     background color is used by the G#Cls routine. Both foreground
  753.     and background colors are used in by G#Write and G#WriteLn.
  754.  
  755.     Here is a list of the corresponding routines, first ASIC, then
  756.     IBRARY (replace the "#" with the appropriate mode number):
  757.  
  758.        REM get the color of a specified point
  759.        colour = POINT(x, y)
  760.        CALL SUB "G#GetPel" x y colour
  761.  
  762.        REM set the color of a specified point
  763.        PSET (x, y), colour
  764.        CALL SUB "G#Color" colour, backgnd
  765.        CALL SUB "G#Plot" x y
  766.  
  767.        REM clear the screen and home the cursor (if any)
  768.        CLS
  769.        CALL SUB "G#Cls"
  770.  
  771.        REM get the current cursor position
  772.        Row = CSRLIN
  773.        Column = POS(0)
  774.        CALL SUB "G#GetLocate" Row Column
  775.  
  776.        REM set the current cursor position
  777.        LOCATE Row, Column
  778.        CALL SUB "G#Locate" Row Column
  779.  
  780.        REM display a string without a carriage return and linefeed
  781.        PRINT St$;
  782.        CALL SUB "G#Write" St$
  783.  
  784.        REM display a string with a carriage return and linefeed
  785.        PRINT St$
  786.        CALL SUB "G#WriteLn" St$
  787.  
  788.     If you need to print a number rather than a string, just use the
  789.     BASIC function STR$ to convert it. If you don't want a leading
  790.     space, you can use the IBRARY routine, StrNB:
  791.  
  792.        CALL SUB "StrNB" Number St$
  793.  
  794.                                Graphics                     page 17
  795.  
  796.  
  797.  
  798.     The IBRARY library has other graphics routines which have no
  799.     ASIC equivalent. Here's a list:
  800.  
  801.        REM get the current colors
  802.        CALL SUB "G#GetColor" Foreground Background
  803.  
  804.        REM draw a line
  805.        CALL SUB "G#Line" x1 y1 x2 y2
  806.  
  807.        REM draw a box (set filled = 0 for frame, = 1 to fill it)
  808.        CALL SUB "G#Box" x1 y1 x2 y2 filled
  809.  
  810.        REM get a VGA palette value
  811.        CALL SUB "GetPalRGB" Colour RedI GreenI BlueI
  812.  
  813.        REM set a VGA palette value
  814.        CALL SUB "SetPalRGB" Colour RedI GreenI BlueI
  815.  
  816.  
  817.     The most obvious aspect of palettes is in the ability to select
  818.     a set of colors suited to a specific application. When showing a
  819.     picture of the sea, you might want mostly blues and greens, for
  820.     instance. There are other implications in the ability to quickly
  821.     change a color across the entire screen, however. It allows for
  822.     simple animation, the ability to fade in or fade out, and other
  823.     interesting effects. Let your imagination run loose and
  824.     experiment a little! You'll be surprised by the power of palette
  825.     manipulation.
  826.  
  827.                                Interrupts                   page 18
  828.  
  829.  
  830.  
  831.     The interrupt routines give you access to some of the more
  832.     common BIOS and DOS interrupts, with a couple of convenience
  833.     features thrown in for good measure.
  834.  
  835.     NOTE that these routines access the computer at a very low
  836.     level. If you don't know what you're doing or make a mistake,
  837.     you could cause serious trouble. Be warned!
  838.  
  839.     Three routines are provided for accessing common interrupts.
  840.     They allow you to set the AX, BX, CX, and DX registers, and
  841.     return the new values of the same, plus the flags.
  842.  
  843.        REM  access to INT 21h, the DOS function handler
  844.        CALL SUB "DosInt" AX BX CX DX Flags
  845.  
  846.        REM  access to INT 10h, the BIOS video handler
  847.        CALL SUB "VidInt" AX BX CX DX Flags
  848.  
  849.        REM  access to INT 16h, the BIOS keyboard handler
  850.        CALL SUB "KbdInt" AX BX CX DX Flags
  851.  
  852.     Each of the 16-bit registers AX, BX, CX and DX can be divided in
  853.     half and accessed as 8-bit values: AH, AL, BH, BL, and so on. To
  854.     make it easier to work with the registers as either 8-bit or
  855.     16-bit quantities, IBRARY includes routines to split a 16-bit
  856.     word into two 8-bit bytes, and vice versa:
  857.  
  858.        CALL SUB "SplitWord" Word HiByte LoByte
  859.  
  860.        CALL SUB "JoinBytes" HiByte LoByte Word
  861.  
  862.     The Flags value is a set of bit flags indicating the value of
  863.     the processor's flag register. Bit 0 contains the carry flag and
  864.     bit 6 contains the zero flag. There are a few other flags
  865.     involved, but you should never need to access them.
  866.  
  867.                                Joystick                     page 19
  868.  
  869.  
  870.  
  871.     The joystick routines allow you to read the positions and
  872.     buttons of up to two joysticks. If only one joystick is
  873.     attached, the results for the second joystick will usually be
  874.     meaningless. In the case of the FlightStick joystick, if only
  875.     one joystick is attached, the value for the Y position of the
  876.     second joystick will indicate the FlightStick throttle setting.
  877.  
  878.     The joysticks are labeled "A" and "B" for these routines, where
  879.     "A" is the first joystick.
  880.  
  881.     You can read the joystick buttons individually or all at once.
  882.     If speed is an issue, you should read the buttons all at once,
  883.     as this is considerably faster than reading them one at a time
  884.     (assuming you wish to read more than one button).
  885.  
  886.        CALL SUB "JButtonA1" Pressed
  887.        CALL SUB "JButtonA2" Pressed
  888.        CALL SUB "JButtonB1" Pressed
  889.        CALL SUB "JButtonB2" Pressed
  890.  
  891.        CALL SUB "JButtons" A1Pressed A2Pressed B1Pressed B2Pressed
  892.  
  893.     The value returned will be -1 if the button is pressed or 0 if
  894.     it is not pressed.
  895.  
  896.     You can also get the position of the joysticks. This is returned
  897.     as a pair of X,Y coordinates for each joystick. The starting and
  898.     ending positions depend on the individual joystick, game
  899.     adapter, and computer, so your program must calibrate itself to
  900.     the individual joystick. I find a range of about 5-140 on my
  901.     FlightStick; your mileage may vary.
  902.  
  903.        CALL SUB "JPos" AX AY BX BY
  904.  
  905.     Note that the joystick routines are BIOS-dependent. They will
  906.     not work on some of the oldest PCs (those made before 1983 or
  907.     thereabouts).
  908.  
  909.                                 Keyboard                    page 20
  910.  
  911.  
  912.     The keyboard routines provide you with information about the
  913.     current state of the keyboard shifts (left and right shift,
  914.     control, and alt keys) and toggles (caps lock, num lock, scroll
  915.     lock, and insert). They also allow you to set the state of the
  916.     keyboard toggles.
  917.  
  918.     To get the state of the left shift, control, or alt keys, you'd
  919.     use one or more of the following:
  920.  
  921.        CALL SUB "LShiftPress" KeyState
  922.        CALL SUB "LCtrlPress" KeyState
  923.        CALL SUB "LAltPress" KeyState
  924.  
  925.     The corresponding routines for the right keys are:
  926.  
  927.        CALL SUB "RShiftPress" KeyState
  928.        CALL SUB "RCtrlPress" KeyState
  929.        CALL SUB "RAltPress" KeyState
  930.  
  931.     Finally, you can tell whether either set of shift, control, or
  932.     alt keys is pressed with these routines:
  933.  
  934.        CALL SUB "ShiftPress" KeyState
  935.        CALL SUB "CtrlPress" KeyState
  936.        CALL SUB "AltPress" KeyState
  937.  
  938.     The KeyState returned will be 0 if the key is not pressed, or -1
  939.     if it is. Please note that the results for LAltPress, RAltPress,
  940.     LCtrlPress, and RCtrlPress will not be meaningful with older AT
  941.     or XT keyboards. They require "enhanced" keyboard support. Older
  942.     keyboards only have a single set of Ctrl and Alt keys, anyway.
  943.  
  944.     You can read the current state of the keyboard toggles, thus:
  945.  
  946.        CALL SUB "GetCapsLock" ToggleState
  947.        CALL SUB "GetInsert" ToggleState
  948.        CALL SUB "GetNumLock" ToggleState
  949.        CALL SUB "GetScrollLock" ToggleState
  950.  
  951.     The result will be 0 if the toggle is off, or -1 if it's on. You
  952.     can set the toggle state using the same conventions, so:
  953.  
  954.        CALL SUB "CapsLock" Status
  955.        CALL SUB "Insert" Status
  956.        CALL SUB "NumLock" Status
  957.        CALL SUB "ScrollLock" Status
  958.  
  959.     If you change the state of a keyboard toggle, the corresponding
  960.     keyboard LED will change as well, except on some of the oldest
  961.     keyboards (or, of course, on keyboards that lack status LEDs).
  962.     Note that it is good practice to save the original states and
  963.     restore them before your program ends-- unless the entire goal
  964.     of your program is to set the keyboard toggles to a desired
  965.     state! Otherwise, you're likely to mess up the user's keyboard
  966.     preferences.
  967.  
  968.                            Memory PEEKs/POKEs               page 21
  969.  
  970.  
  971.     For direct memory access, nothing beats good ol' PEEK and
  972.     POKE... especially when they're extended to cover all common
  973.     variable types! IBRARY lets you read or write blocks of memory
  974.     ranging from bytes to strings.
  975.  
  976.        REM read a byte from memory into an integer
  977.        CALL SUB "PeekB" Segment Offset Value
  978.  
  979.        REM read an integer from memory
  980.        CALL SUB "PeekI" Segment Offset Value
  981.  
  982.        REM read a long integer from memory
  983.        CALL SUB "PeekL" Segment Offset Value&
  984.  
  985.        REM read up to 80 bytes from memory into a string
  986.        CALL SUB "PeekS" Segment Offset Bytes Value$
  987.  
  988.        REM write a byte to memory from an integer
  989.        CALL SUB "PokeB" Segment Offset Value
  990.  
  991.        REM write an integer to memory
  992.        CALL SUB "PokeI" Segment Offset Value
  993.  
  994.        REM write a long integer to memory
  995.        CALL SUB "PokeL" Segment Offset Value&
  996.  
  997.        REM write up to 80 bytes to memory from a string
  998.        CALL SUB "PokeS" Segment Offset Bytes Value$
  999.  
  1000.     Note that strings can handle only up to 80 bytes, due to an ASIC
  1001.     limitation. Also, the results of PeekS may not be a normal ASIC
  1002.     string, if it contains null characters (CHR$(0), which marks the
  1003.     end of a traditional ASIC string). There is nothing wrong with
  1004.     this, as such, but remember that the string ends at the first
  1005.     CHR$(0) as far as ASIC is concerned-- so it won't see any
  1006.     characters which come after the first CHR$(0).
  1007.  
  1008.     For experimentation-- note that MDA video screens begin at
  1009.     segment -20480, offset 0; color video screens begin at segment
  1010.     -18432, offset 0. An 80x25 text-mode screen takes up 4000 bytes
  1011.     in either case (80x25 characters + 80x25 color/attribute codes).
  1012.     An assortment of useful information can be read from the BIOS
  1013.     data area, which begins at segment 64, offset 0-- check your
  1014.     local BBS for a good PEEK/POKE list! The old PEEKPOKE.TXT or the
  1015.     MEMORY.LST file provided with the INTER##.ZIP files would be a
  1016.     good place to start.
  1017.  
  1018.                                  Mouse                      page 22
  1019.  
  1020.  
  1021.     The mouse routines provide full-featured mouse support. You can
  1022.     see if a mouse is available and how many buttons it has, get the
  1023.     cursor position (either the current position or the position at
  1024.     the last press or release of a specified button), set the cursor
  1025.     position, change the cursor, set the mouse range, get hardware
  1026.     information about the mouse, and so on.
  1027.  
  1028.     There are two unusual mouse modes to be aware of. One is text
  1029.     mode, which is mapped to a 640x200 virtual display. So, to
  1030.     convert the results to text format, you need to divide the
  1031.     cursor position by eight and add one. To convert from text
  1032.     format, subtract one and multiply by eight.
  1033.  
  1034.     The second unusual mode is 320x200 CGA mode, which is also
  1035.     mapped to 640x200. To convert the coordinates to this mode,
  1036.     divide X by two. To convert from this mode, multiply the X
  1037.     coordinate by two.
  1038.  
  1039.     All other modes use the actual display coordinates instead of a
  1040.     bizarro virtual screen. Why the peculiar CGA and text modes?
  1041.     Well, evidently Microsoft never thought there'd be any video
  1042.     adapters besides MDA and CGA, and decided to create a single
  1043.     virtual screen size that worked for all modes. Not a bad idea, I
  1044.     guess, but rather shortsighted. Oh well.
  1045.  
  1046.     One other nuisance that you may run into is that the mouse
  1047.     cursor can't be directly turned on or off. A "cursor visibility"
  1048.     count is maintained-- if the mouse cursor was turned on twice,
  1049.     you'll need to turn it off twice before it will actually
  1050.     disappear.
  1051.  
  1052.     Before using the mouse, you must initialize it. The
  1053.     initialization routine also checks to make sure that a mouse is
  1054.     installed and tells you how many buttons it has. It's best to
  1055.     initialize the mouse after setting the screen mode, so the mouse
  1056.     driver understands what mode you're using. Not all mouse drivers
  1057.     support all screen modes, but you can reasonably expect any
  1058.     current mouse driver to support MDA, CGA, EGA, and VGA. Hercules
  1059.     graphics mode is rarely supported, as it must be set through
  1060.     direct hardware access rather than the standard techniques, so
  1061.     the mouse driver has little way of knowing that you've changed
  1062.     the mode.
  1063.  
  1064.     The mouse routines will work equally well with two-button or
  1065.     three-button rodents. The middle button functions will return 0
  1066.     with two-button mice.
  1067.  
  1068.                                  Mouse                      page 23
  1069.  
  1070.  
  1071.  
  1072.     I won't go into great detail on these routines, because they're
  1073.     pretty much self-explanatory. The mouse is a fairly easy device
  1074.     to deal with, despite the quirks of Microsoft's driver.
  1075.  
  1076.     You can initialize the mouse driver like so:
  1077.  
  1078.        CALL SUB "MInit" Buttons
  1079.  
  1080.     This returns the number of mouse buttons available. If there is
  1081.     no mouse, zero will be returned. Initialize the mouse AFTER
  1082.     setting the screen mode, so it knows what the screen is like.
  1083.  
  1084.     You can make the mouse cursor visible or invisible. It will
  1085.     function just as well in either state. See the previous page for
  1086.     some quirks.
  1087.  
  1088.        CALL SUB "MShow"
  1089.        CALL SUB "MHide"
  1090.  
  1091.     There are many ways to get the mouse cursor position. You can
  1092.     get the current position, the position at which the mouse was
  1093.     located when a particular button was pressed, or the position
  1094.     when a button was released. If you choose a past position, you
  1095.     can also find out how many presses or releases of the button
  1096.     have taken place since you last checked.
  1097.  
  1098.        REM current coordinates
  1099.        CALL SUB "MWhereX" X
  1100.        CALL SUB "MWhereY" Y
  1101.  
  1102.        REM number of presses of a given button
  1103.        REM and mouse position at last press
  1104.        CALL SUB "MLClick" Count X Y
  1105.        CALL SUB "MMClick" Count X Y
  1106.        CALL SUB "MRClick" Count X Y
  1107.  
  1108.        REM number of releases of a given button
  1109.        REM and mouse position at last release
  1110.        CALL SUB "MLRelease" Count X Y
  1111.        CALL SUB "MMRelease" Count X Y
  1112.        CALL SUB "MRRelease" Count X Y
  1113.  
  1114.                                  Mouse                      page 24
  1115.  
  1116.  
  1117.  
  1118.     If you'd prefer to find out which buttons are currently pressed,
  1119.     no problem:
  1120.  
  1121.        CALL SUB "MLButton" IsDown
  1122.        CALL SUB "MMButton" IsDown
  1123.        CALL SUB "MRButton" IsDown
  1124.  
  1125.     Of course, you can also set the cursor location:
  1126.  
  1127.        CALL SUB "MLocate" X Y
  1128.  
  1129.     The mouse cursor range can be restricted to a given area of the
  1130.     screen. This area is expressed by giving the upper left corner
  1131.     and lower right corner of the rectangular area to which to
  1132.     restrict the cursor.
  1133.  
  1134.        CALL SUB "MWindow" X1 Y1 X2 Y2
  1135.  
  1136.     There are a variety of cursor shapes available for graphics
  1137.     mode:
  1138.  
  1139.         0    hourglass ("please wait, program is working" symbol)
  1140.         1    pointing arrow (default)
  1141.         2    pointing hand
  1142.         3    crosshair
  1143.         4    target (box in a box)
  1144.         5    grabbing hand
  1145.  
  1146.     If you have ideas for more, let me know and I'll see what I can
  1147.     do. Cursor shapes are not unduly difficult to define, although
  1148.     it's technical enough so that I decided to avoid confusion by
  1149.     leaving direct handling out of IBRARY.
  1150.  
  1151.        CALL SUB "MCursorG" CursorNr
  1152.  
  1153.                              Miscellaneous                  page 25
  1154.  
  1155.  
  1156.  
  1157.     If there are not (yet) enough routines in a category to give
  1158.     them their own classification, they come to roost here, in good
  1159.     ol' Miscellaneous. At the moment, this consists of a string
  1160.     routine and some DOS output routines.
  1161.  
  1162.     The StrNB routine works like ASIC's built-in STR$ function, but
  1163.     strips all leading blanks from the result. It works on plain
  1164.     integers.
  1165.  
  1166.        CALL SUB "StrNB" Number Result$
  1167.  
  1168.     The DOS output routines allow you to send output to the default
  1169.     DOS device-- normally the screen, although it can be redirected
  1170.     by the user to another device or to a file. We start with a
  1171.     generic PRINT replacement:
  1172.  
  1173.        CALL SUB "DosPrint" St$
  1174.  
  1175.     That sends a string to standard output. If you want a carriage
  1176.     return and linefeed, you must add them yourself:
  1177.  
  1178.        CrLf$ = CHR$(13) + CHR$(10)
  1179.        St$ = St$ + CrLf$
  1180.  
  1181.     The rest of the DOS output routines require ANSI.SYS or another
  1182.     ANSI driver to be loaded. They send the appropriate ANSI codes
  1183.     to standard output.
  1184.  
  1185.        CALL SUB "DosCls"
  1186.  
  1187.        CALL SUB "DosColor" Foreground Background
  1188.  
  1189.        CALL SUB "DosLocate" Row Column
  1190.  
  1191.     It's now possible to get and set the state of the cursor, too.
  1192.     This is based on BIOS routines and is meant for use in text
  1193.     mode. The size and shape of the cursor is given in scan lines,
  1194.     which may range from about 8-16 depending on the display adapter
  1195.     and the size of your character font (which is related to the
  1196.     number of text rows on the screen).
  1197.  
  1198.        CALL SUB "CursorInfo" Visible StartLine EndLine MaxLine
  1199.  
  1200.     The VISIBLE variable will return zero if the cursor is not
  1201.     visible. The others return scan lines, which start at zero and
  1202.     end at whatever MAXLINE returns. You can set the cursor size and
  1203.     shape with:
  1204.  
  1205.        CALL SUB "SetCursor" StartLine EndLine
  1206.  
  1207.     Use a value of 32 for STARTLINE to make the cursor invisible. If
  1208.     you call SetCursor, you should also use CursorInfo, and set the
  1209.     original cursor shape back before ending your program.
  1210.  
  1211.                              Miscellaneous                  page 26
  1212.  
  1213.  
  1214.  
  1215.     Ibrary supports simple pop-up windows, too. You select the upper
  1216.     left corner and lower right corners of the window frame, a frame
  1217.     type, the color to use, and a title. If you don't want a title,
  1218.     just use a null string (""). Frame types may be any of:
  1219.  
  1220.        0     no frame
  1221.        1     single lines
  1222.        2     double lines
  1223.        3     single horizontal lines, double vertical lines
  1224.        4     double horizontal lines, single vertical lines
  1225.  
  1226.     The COLOUR value may include both foreground and background
  1227.     colors, using the formula: Colour = Backgnd * 16 + Foregnd.
  1228.  
  1229.        CALL SUB "PopWindow" TRow LCol BRow RCol Frame Colour Title$
  1230.  
  1231.     You can save (or restore) an 80x25 text screen, for either a
  1232.     mono or color display, with ScrSave and ScrRest. You'll need to
  1233.     specify the first element of a 2000-element integer array, the
  1234.     screen page (normally zero), and the video type (normally -1 for
  1235.     top speed; use 0 only if you're working with a CGA display and
  1236.     experience irritating "snow" during the save/restore.
  1237.  
  1238.        CALL SUB "ScrSave" ScreenArray(1) PageNr FastVideo
  1239.        CALL SUB "ScrRest" ScreenArray(1) PageNr FastVideo
  1240.  
  1241.     Want to delay for a while? IBRARY provides rock-solid delay
  1242.     routines that were designed to cope with multitasking and
  1243.     crossing the midnight boundary-- areas which can often cause
  1244.     havoc with homebrew delay routines. You can delay for a
  1245.     specified number of seconds or eighteenths of seconds:
  1246.  
  1247.        CALL SUB "Delay" Seconds
  1248.        CALL SUB "Delay18th" SplitSeconds
  1249.  
  1250.                              Miscellaneous                  page 27
  1251.  
  1252.  
  1253.  
  1254.     While ASIC provides a perfectly useful SOUND statement, it's not
  1255.     compatible with the one in Microsoft BASICs. This sound routine
  1256.     works just like the MS BASIC version, with the exception of
  1257.     taking a integer duration in 1/18th seconds.
  1258.  
  1259.        CALL SUB "Sound" Frequency Duration
  1260.  
  1261.     Useful frequencies run from around 50-4000. If you aim to make
  1262.     music using this service, the following table may prove of some
  1263.     use. You can move down an octave by halving the frequency for a
  1264.     given note. About seven octaves are available on the usual PC
  1265.     compatible.
  1266.  
  1267.        Note     Frequency (highest octave)
  1268.        =====    =========
  1269.          A         3520
  1270.        A#,B-       3714
  1271.          B         3952
  1272.          C         4186
  1273.        C#,D-       4434
  1274.          D         4698
  1275.        D#,E-       4978
  1276.          E         5274
  1277.          F         5588
  1278.        F#,G-       5920
  1279.          G         6272
  1280.        G#,A-       6644
  1281.  
  1282.